const test = require('ava')

const { TAU } = require('../maths/constants')
const path2 = require('../geometries/path2')

const comparePoints = require('../../test/helpers/comparePoints')

const { arc } = require('./index')

test('arc (defaults)', (t) => {
  const geometry = arc()
  const obs = path2.toPoints(geometry)

  t.notThrows(() => path2.validate(geometry))
  t.deepEqual(obs.length, 33)
})

test('arc (options)', (t) => {
  // test center
  let exp = [
    [3, 2],
    [2.9324722294043557, 2.361241666187153],
    [2.739008917220659, 2.6736956436465573],
    [2.4457383557765384, 2.8951632913550625],
    [2.092268359463302, 2.9957341762950342],
    [1.7263370099279172, 2.961825643172819],
    [1.3973653636207437, 2.7980172272802397],
    [1.1497828642703858, 2.526432162877356],
    [1.017026900316098, 2.1837495178165702],
    [1.017026900316098, 1.8162504821834298],
    [1.149782864270386, 1.4735678371226442],
    [1.3973653636207435, 1.2019827727197605],
    [1.726337009927917, 1.0381743568271808],
    [2.0922683594633016, 1.0042658237049653],
    [2.4457383557765384, 1.1048367086449378],
    [2.739008917220659, 1.326304356353443],
    [2.9324722294043557, 1.6387583338128469]
  ]
  let geometry = arc({ center: [2, 2], segments: 16 })
  let obs = path2.toPoints(geometry)

  t.notThrows(() => path2.validate(geometry))
  t.deepEqual(obs.length, 17)
  t.true(comparePoints(obs, exp))

  // test radius
  exp = [
    [2, 0],
    [1.8649444588087116, 0.7224833323743058],
    [1.4780178344413182, 1.3473912872931144],
    [0.8914767115530766, 1.7903265827101247],
    [0.18453671892660403, 1.991468352590069],
    [-0.5473259801441658, 1.923651286345638],
    [-1.2052692727585126, 1.5960344545604792],
    [-1.7004342714592284, 1.0528643257547114],
    [-1.9659461993678036, 0.36749903563314074],
    [-1.9659461993678036, -0.36749903563314024],
    [-1.7004342714592282, -1.0528643257547117],
    [-1.205269272758513, -1.596034454560479],
    [-0.5473259801441662, -1.923651286345638],
    [0.1845367189266031, -1.9914683525900692],
    [0.8914767115530771, -1.7903265827101245],
    [1.4780178344413184, -1.3473912872931142],
    [1.8649444588087116, -0.7224833323743061]
  ]
  geometry = arc({ radius: 2, segments: 16 })
  obs = path2.toPoints(geometry)

  t.notThrows(() => path2.validate(geometry))
  t.deepEqual(obs.length, 17)
  t.true(comparePoints(obs, exp))

  // test startAngle
  exp = [
    [6.123233995736766e-17, 1],
    [-0.3546048870425357, 0.9350162426854148],
    [-0.6631226582407953, 0.748510748171101],
    [-0.8854560256532098, 0.4647231720437687],
    [-0.992708874098054, 0.12053668025532308],
    [-0.970941817426052, -0.23931566428755788],
    [-0.8229838658936566, -0.5680647467311556],
    [-0.5680647467311559, -0.8229838658936564],
    [-0.23931566428755774, -0.970941817426052],
    [0.1205366802553232, -0.992708874098054],
    [0.4647231720437688, -0.8854560256532098],
    [0.7485107481711007, -0.6631226582407955],
    [0.9350162426854147, -0.35460488704253595],
    [1, -2.4492935982947064e-16]
  ]
  geometry = arc({ startAngle: TAU / 4, segments: 16 })
  obs = path2.toPoints(geometry)

  t.notThrows(() => path2.validate(geometry))
  t.deepEqual(obs.length, 14)
  t.true(comparePoints(obs, exp))

  // test endAngle
  exp = [
    [1, 0],
    [0.9510565162951535, 0.3090169943749474],
    [0.8090169943749475, 0.5877852522924731],
    [0.5877852522924731, 0.8090169943749475],
    [0.30901699437494745, 0.9510565162951535],
    [6.123233995736766e-17, 1]
  ]
  geometry = arc({ endAngle: TAU / 4, segments: 16 })
  obs = path2.toPoints(geometry)

  t.notThrows(() => path2.validate(geometry))
  t.deepEqual(obs.length, 6)
  t.true(comparePoints(obs, exp))

  // test makeTangent
  exp = [
    [1, 0],
    [0.9957341762950345, 0.09226835946330199],
    [0.8999557329057603, 0.43598128263728936],
    [0.6896020498551045, 0.7241885202318785],
    [0.391453692861967, 0.9201978082699006],
    [0.04346855052920052, 0.9990547958520045],
    [-0.31005066355011174, 0.9507200355689026],
    [-0.6240966815770753, 0.781347126470996],
    [-0.858687650595474, 0.5124992865505523],
    [-0.9839573055048071, 0.1784040945262181],
    [-0.9839573055048071, -0.1784040945262183],
    [-0.8586876505954741, -0.5124992865505521],
    [-0.6240966815770755, -0.7813471264709959],
    [-0.3100506635501122, -0.9507200355689025],
    [0.04346855052920005, -0.9990547958520045],
    [0.39145369286196696, -0.9201978082699006],
    [0.6896020498551043, -0.7241885202318787],
    [0.8999557329057604, -0.435981282637289],
    [0.9957341762950345, -0.09226835946330197]
  ]
  geometry = arc({ makeTangent: true, segments: 16 })
  obs = path2.toPoints(geometry)

  t.notThrows(() => path2.validate(geometry))
  t.deepEqual(obs.length, 19)
  t.true(comparePoints(obs, exp))

  // test segments
  exp = [
    [1, 0],
    [0.766044443118978, 0.6427876096865393],
    [0.17364817766693041, 0.984807753012208],
    [-0.4999999999999998, 0.8660254037844387],
    [-0.9396926207859083, 0.3420201433256689],
    [-0.9396926207859084, -0.34202014332566866],
    [-0.5000000000000004, -0.8660254037844385],
    [0.17364817766692997, -0.9848077530122081],
    [0.7660444431189778, -0.6427876096865396]
  ]
  geometry = arc({ segments: 8 })
  obs = path2.toPoints(geometry)

  t.notThrows(() => path2.validate(geometry))
  t.deepEqual(obs.length, 9)
  t.true(comparePoints(obs, exp))
})

test('arc (rotations)', (t) => {
  let exp = [
    [6.123233995736766e-17, 1],
    [-0.30901699437494734, 0.9510565162951536],
    [-0.587785252292473, 0.8090169943749475],
    [-0.8090169943749473, 0.5877852522924732],
    [-0.9510565162951535, 0.3090169943749475],
    [-1, 1.2246467991473532e-16]
  ]
  let geometry = arc({ startAngle: TAU / 4, endAngle: TAU / 2, segments: 16 })
  let obs = path2.toPoints(geometry)

  t.notThrows(() => path2.validate(geometry))
  t.deepEqual(obs.length, 6)
  t.true(comparePoints(obs, exp))

  exp = [
    [-1, 1.2246467991473532e-16],
    [-0.9396926207859084, -0.34202014332566866],
    [-0.7660444431189781, -0.6427876096865393],
    [-0.5000000000000004, -0.8660254037844385],
    [-0.17364817766693033, -0.984807753012208],
    [0.17364817766692997, -0.9848077530122081],
    [0.49999999999999933, -0.866025403784439],
    [0.7660444431189778, -0.6427876096865396],
    [0.9396926207859084, -0.3420201433256686],
    [1, -2.4492935982947064e-16]
  ]
  geometry = arc({ startAngle: TAU / 2, endAngle: TAU, segments: 16 })
  obs = path2.toPoints(geometry)

  t.notThrows(() => path2.validate(geometry))
  t.deepEqual(obs.length, 10)
  t.true(comparePoints(obs, exp))

  exp = [
    [-1.8369701987210297e-16, -1],
    [0.34202014332566816, -0.9396926207859085],
    [0.6427876096865393, -0.7660444431189781],
    [0.8660254037844384, -0.5000000000000004],
    [0.984807753012208, -0.1736481776669304],
    [0.9848077530122081, 0.17364817766692991],
    [0.866025403784439, 0.4999999999999993],
    [0.6427876096865396, 0.7660444431189778],
    [0.34202014332566866, 0.9396926207859084],
    [3.061616997868383e-16, 1]
  ]
  geometry = arc({ startAngle: TAU * 0.75, endAngle: TAU / 4, segments: 16 })
  obs = path2.toPoints(geometry)

  t.notThrows(() => path2.validate(geometry))
  t.deepEqual(obs.length, 10)
  t.true(comparePoints(obs, exp))

  exp = [[-1.8369701987210297e-16, -1]]
  geometry = arc({ startAngle: TAU * 0.75, endAngle: 270.000000005 * 0.017453292519943295, segments: 16 })
  obs = path2.toPoints(geometry)

  t.notThrows(() => path2.validate(geometry))
  t.deepEqual(obs.length, 1)
  t.true(comparePoints(obs, exp))
})
